package com.icode.mvc.dispatch;

import com.icode.mvc.controller.Controller;
import com.icode.mvc.controller.key.Key;
import com.icode.mvc.model.Model;
import com.icode.mvc.util.KeyGenerator;
import com.icode.mvc.util.SimpleKeyGenerator;
import com.icode.mvc.util.SimpleMethodKeyGenerator;
import com.icode.mvc.view.View;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * User: Alex Zhong
 * Date: 2016/2/3
 */
public class DispatchServlet extends GenericServlet {
    private Map<Key, Controller> controllers = new ConcurrentHashMap<Key, Controller>();

    private List<KeyGenerator> keyGenerators = new ArrayList<KeyGenerator>();

    @Override
    public void init(ServletConfig config) throws ServletException {
        //init the key generators
        keyGenerators.add(new SimpleKeyGenerator());
        keyGenerators.add(new SimpleMethodKeyGenerator());

        //init the map of controllers here
        throw new UnsupportedOperationException("Not yet implemented!");
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        Controller controller = null;
        for (KeyGenerator keyGenerator : keyGenerators) {
            Key key = keyGenerator.generate(request);
            controller = controllers.get(key);
            if (controller != null) {
                break;
            }
        }

        if (controller == null) {
            throw new UnsupportedOperationException("no controller mapped in the controllers map");
        }

        ModelAndView modelAndView = controller.control(request, response);

        Model model = modelAndView.getModel();

        View view = modelAndView.getView();

        view.render(request, response, model);
    }
}
